%C:\git-local\umark\cpp\g001-clone-2015-03-09-nowy\g001>cd C:\git-local\umark\cpp\g001-clone-2015-03-09-nowy\g001\cpp\interpretuj\typwartosc

% cd ../../..

\path{cpp/interpretuj/typwartosc/}

Plik {\sf wartosc.h}.
\begin{lstC}
#ifndef WARTOSC_H
#define WARTOSC_H

typedef union WartoscTag {
  int i;
  char c;
  float f;
  double d;
  long l;
} Wartosc;

#endif // WARTOSC_H
\end{lstC}


Plik {\sf typwartosc.h}.
\begin{lstC}
#ifndef TYPWARTOSC_H
#define TYPWARTOSC_H

#include "wartosc.h"

typedef struct TypWartoscTag {
  char typ; 
  Wartosc w;
} TypWartosc;

#endif // TYPWARTOSC_H


/*
  typ przyjmuje
  error 'e'
  int 'i';
  char 'c';
  float 'f';
  double 'd';
  long 'l';
  */
\end{lstC}


Plik {\sf lista.h}.
\begin{lstC}
#ifndef LISTA_H
#define LISTA_H

#include "typwartosc.h"

#include <stdio.h>

typedef struct ElementTag {
  TypWartosc tw;
  struct ElementTag *pNext;
} Element;

typedef struct ListaTag {
  Element *pFirst;
  Element *pLast;
} Lista;

void ListaInicjalizacja(Lista *pLista);

void ListaDodajOstatniInt(Lista *pLista, char typ, int i);

void ListaUsunOstatniInt(Lista *pLista);

void ListaDrukuj(Lista *pLista);

#endif // LISTA_H
\end{lstC}


Plik {\sf lista.c}.
\begin{lstC}
#include "lista.h"

#include <stdlib.h>

void ListaInicjalizacja(Lista *pLista) {
  pLista->pFirst = NULL;
  pLista->pLast  = NULL;
}

void ListaDodajOstatniInt(Lista *pLista, char typ, int i) {
  TypWartosc tw;
  Element *pE;
  tw.typ = 'i';
  tw.w.i = i;
  pE = malloc( sizeof(Element) );
  pE->tw = tw;
  pE->pNext = NULL;
  if (pLista->pFirst == NULL) {
    pLista->pFirst = pE;
	pLista->pLast = pE;
  } else {
    pLista->pLast->pNext = pE;
    pLista->pLast = pE;
  }
  printf("first: %x\n", pLista->pFirst);
  printf("last: %x\n", pLista->pLast);
}

void ListaUsunOstatni(Lista *pLista) {
  Element *pBeforeLast;
  if (pLista->pFirst == NULL) {
    printf("Lista jest pusta\n");
  } else if (pLista->pFirst == pLista->pLast) { // jeden element
    printf("Ostatni: %x -> %x\n", pLista->pLast, pLista->pLast->pNext); 
    free(pLista->pLast);
	pLista->pFirst = NULL;
    pLista->pLast  = NULL;
  }
  else { // więcej niż jeden element
    printf("Ostatni: %x -> %x\n", pLista->pLast, pLista->pLast->pNext);   
    pBeforeLast = pLista->pFirst;
	printf("%x -> %x\n", pBeforeLast, pBeforeLast->pNext);
    while (pBeforeLast->pNext != pLista->pLast) {
	  pBeforeLast = pBeforeLast->pNext;
	  printf("%x -> %x\n", pBeforeLast, pBeforeLast->pNext);
	}
	free(pLista->pLast);
	pBeforeLast->pNext = NULL;	
	pLista->pLast = pBeforeLast; // nowy iostatni
  }
}

void ListaDrukuj(Lista *pLista) {
  Element *pE;
  pE = pLista->pFirst;
  while (pE != NULL) {
    if(pE->tw.typ == 'i') {
	  printf("%d ", pE->tw.w.i);
	}	
    pE = pE->pNext;
  }
  printf("\n");
}
\end{lstC}


Plik {\sf main.c}.
\begin{lstC}
#include <stdio.h>

#include "lista.h"

int main(void) {
  Lista li;
  ListaInicjalizacja(&li);

  ListaDodajOstatniInt(&li, 'i', 10);
  printf("%d\n", li.pFirst->tw.w.i);
  printf("Wydruk listy 1\n");
  ListaDrukuj(&li);
  printf("Usuwam ostatni\n");
  ListaUsunOstatni(&li);
  printf("Wydruk listy 0\n");
  ListaDrukuj(&li);
  
  ListaDodajOstatniInt(&li, 'i', 2);
  ListaDodajOstatniInt(&li, 'i', 4);
  ListaDodajOstatniInt(&li, 'i', 6);
  printf("Wydruk listy 3\n");
  ListaDrukuj(&li);
  printf("Usuwam ostatni\n");
  ListaUsunOstatni(&li);
  printf("Wydruk listy 2\n");
  ListaDrukuj(&li);
  printf("Usuwam ostatni \n");
  ListaUsunOstatni(&li);
  printf("Wydruk listy 1\n");
  ListaDrukuj(&li);
  printf("Usuwam ostatni\n");
  ListaUsunOstatni(&li);
  printf("Wydruk listy\n");
  ListaDrukuj(&li);
  
  // próba usunięcia z pustej
  printf("Usuwam ostatni\n");
  ListaUsunOstatni(&li);
  return 0;
}
\end{lstC}


Plik {\sf }.
\begin{lstMake}
C_FLAGS=-Wall -Wextra
C_DEBUG_FLAGS= $(C_FLAGS) -g
C_RELEASE_FLAGS= $(C_FLAGS) -O3
L_FLAGS=

SOURCES = main.c lista.c
RELEASE_OBJECTS = $(SOURCES:.c=.o)
DEBUG_OBJECTS = $(addprefix dbg_,$(SOURCES:.c=.o))

all: release debug

release: $(RELEASE_OBJECTS)
	gcc $^ -o $@ $(LFLAGS)

$(RELEASE_OBJECTS): %.o: %.c
	gcc -c $< -o $@ $(C_RELEASE_FLAGS)
	
debug: $(DEBUG_OBJECTS)
	gcc $^ -o $@ -LFLAGS

$(DEBUG_OBJECTS): dbg_%.o: %.c
	gcc -c $< -o $@ $(C_DEBUG_FLAGS)
	
clean:
	rm -f *.o

.PHONY: clean	
\end{lstMake}

